require "crypto/bcrypt/password"

class <%= class_name %> < Granite::Base
  include Crypto
  connection <%= config.database %>
  <%= "table #{table_name}" %>

  column id : Int64, primary: true
<% @fields.reject{|f| f.hidden }.each do |field| -%>
  column <%= field.name %> : <%= field.cr_type %>?
<% end -%>
<% if config.database != "sqlite" -%>
  timestamps
<% end -%>

  validate :email, "is required", ->(<%= @name %> : <%= class_name %>) do
    (email = <%= @name %>.email) ? !email.empty? : false
  end

  validate :email, "already in use", ->(<%= @name %> : <%= class_name %>) do
    existing = <%= class_name %>.find_by email: <%= @name %>.email
    !existing || existing.id == <%= @name %>.id
  end

  validate :password, "is too short", ->(<%= @name %> : <%= class_name %>) do
    <%= @name %>.password_changed? ? <%= @name %>.valid_password_size? : true
  end

  def password=(password)
    @new_password = password
    @hashed_password = Bcrypt::Password.create(password, cost: 10).to_s
  end

  def password
    (hash = hashed_password) ? Bcrypt::Password.new(hash) : nil
  end

  def password_changed?
    new_password ? true : false
  end

  def valid_password_size?
    (pass = new_password) ? pass.size >= 8 : false
  end

  def authenticate(password : String)
    (bcrypt_pass = self.password) ? bcrypt_pass.verify(password) : false
  end

  private getter new_password : String?
end
